//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package http_custom_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas-org/api-server/api_common"
	"atomgit.com/openlinksaas-org/api-server/dao"
	"atomgit.com/openlinksaas-org/api-server/dao/api_coll_dao"
	"atomgit.com/openlinksaas-org/api-server/dao/project_entry_dao"
	"atomgit.com/openlinksaas-org/api-server/utils"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/http_custom_api"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/project_entry_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
)

func (apiImpl *HttpCustomApiImpl) CreateGroup(ctx context.Context, req *http_custom_api.CreateGroupRequest) (*http_custom_api.CreateGroupResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &http_custom_api.CreateGroupResponse{
			Code:   http_custom_api.CreateGroupResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, roleItem, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &http_custom_api.CreateGroupResponse{
			Code:   http_custom_api.CreateGroupResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &http_custom_api.CreateGroupResponse{
			Code:   http_custom_api.CreateGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &http_custom_api.CreateGroupResponse{
			Code:   http_custom_api.CreateGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	//检查信息是否存在
	entryItem, err := project_entry_dao.EntryDao.Get(ctx, req.ApiCollId, req.ProjectId)
	if err != nil {
		return &http_custom_api.CreateGroupResponse{
			Code:   http_custom_api.CreateGroupResponse_CODE_NO_CUSTOM_API,
			ErrMsg: "自定义接口不存在",
		}, nil
	}
	if entryItem.EntryType != uint32(project_entry_api.ENTRY_TYPE_ENTRY_TYPE_API_COLL) {
		return &http_custom_api.CreateGroupResponse{
			Code:   http_custom_api.CreateGroupResponse_CODE_NO_CUSTOM_API,
			ErrMsg: "自定义接口不存在",
		}, nil
	}

	hasUpdatePerm := api_common.CheckEntryCanUpdate(sessionItem, projectItem, roleItem, entryItem)

	if !hasUpdatePerm {
		return &http_custom_api.CreateGroupResponse{
			Code:   http_custom_api.CreateGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	groupId := uuid.NewString()
	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = api_coll_dao.ApiGroupDao.Insert(sessCtx, &api_coll_dao.ApiGroupInfoDbItem{
			GroupId:   groupId,
			ApiCollId: req.ApiCollId,
			GroupName: req.GroupName,
			ItemCount: 0,
			TimeStamp: nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &http_custom_api.CreateGroupResponse{
			Code:    http_custom_api.CreateGroupResponse_CODE_OK,
			GroupId: groupId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*http_custom_api.CreateGroupResponse), nil
}

func (apiImpl *HttpCustomApiImpl) UpdateGroup(ctx context.Context, req *http_custom_api.UpdateGroupRequest) (*http_custom_api.UpdateGroupResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &http_custom_api.UpdateGroupResponse{
			Code:   http_custom_api.UpdateGroupResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, roleItem, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &http_custom_api.UpdateGroupResponse{
			Code:   http_custom_api.UpdateGroupResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &http_custom_api.UpdateGroupResponse{
			Code:   http_custom_api.UpdateGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &http_custom_api.UpdateGroupResponse{
			Code:   http_custom_api.UpdateGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	//检查信息是否存在
	entryItem, err := project_entry_dao.EntryDao.Get(ctx, req.ApiCollId, req.ProjectId)
	if err != nil {
		return &http_custom_api.UpdateGroupResponse{
			Code:   http_custom_api.UpdateGroupResponse_CODE_NO_CUSTOM_API,
			ErrMsg: "自定义接口不存在",
		}, nil
	}
	if entryItem.EntryType != uint32(project_entry_api.ENTRY_TYPE_ENTRY_TYPE_API_COLL) {
		return &http_custom_api.UpdateGroupResponse{
			Code:   http_custom_api.UpdateGroupResponse_CODE_NO_CUSTOM_API,
			ErrMsg: "自定义接口不存在",
		}, nil
	}

	hasUpdatePerm := api_common.CheckEntryCanUpdate(sessionItem, projectItem, roleItem, entryItem)

	if !hasUpdatePerm {
		return &http_custom_api.UpdateGroupResponse{
			Code:   http_custom_api.UpdateGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := api_coll_dao.ApiGroupDao.Exist(ctx, req.ApiCollId, req.GroupId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &http_custom_api.UpdateGroupResponse{
			Code:   http_custom_api.UpdateGroupResponse_CODE_NO_GROUP,
			ErrMsg: "接口集分组不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = api_coll_dao.ApiGroupDao.Update(sessCtx, req.ApiCollId, req.GroupId, req.GroupName)
		if err != nil {
			return nil, err
		}
		return &http_custom_api.UpdateGroupResponse{
			Code: http_custom_api.UpdateGroupResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*http_custom_api.UpdateGroupResponse), nil
}

func (apiImpl *HttpCustomApiImpl) ListGroup(ctx context.Context, req *http_custom_api.ListGroupRequest) (*http_custom_api.ListGroupResponse, error) {
	emptyList := []*http_custom_api.ApiGroupInfo{}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &http_custom_api.ListGroupResponse{
			Code:      http_custom_api.ListGroupResponse_CODE_WRONG_SESSION,
			ErrMsg:    "会话不存在",
			GroupList: emptyList,
		}, nil
	}
	_, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &http_custom_api.ListGroupResponse{
			Code:      http_custom_api.ListGroupResponse_CODE_NO_PROJECT,
			ErrMsg:    "项目不存在",
			GroupList: emptyList,
		}, nil
	} else if err == utils.ErrNoRole {
		return &http_custom_api.ListGroupResponse{
			Code:      http_custom_api.ListGroupResponse_CODE_NO_PERMISSION,
			ErrMsg:    "没有权限",
			GroupList: emptyList,
		}, nil
	} else if err != nil {
		return nil, err
	}

	exist, err := api_coll_dao.CustomExtraDao.Exist(ctx, req.ApiCollId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &http_custom_api.ListGroupResponse{
			Code:      http_custom_api.ListGroupResponse_CODE_NO_CUSTOM_API,
			ErrMsg:    "自定义接口集不存在",
			GroupList: emptyList,
		}, nil
	}
	groupItemList, err := api_coll_dao.ApiGroupDao.List(ctx, req.ApiCollId)
	if err != nil {
		return nil, err
	}
	groupList := []*http_custom_api.ApiGroupInfo{}
	for _, groupItem := range groupItemList {
		groupList = append(groupList, groupItem.ToApiGroupInfo())
	}
	return &http_custom_api.ListGroupResponse{
		Code:      http_custom_api.ListGroupResponse_CODE_OK,
		GroupList: groupList,
	}, nil
}

func (apiImpl *HttpCustomApiImpl) RemoveGroup(ctx context.Context, req *http_custom_api.RemoveGroupRequest) (*http_custom_api.RemoveGroupResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, roleItem, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	//检查信息是否存在
	entryItem, err := project_entry_dao.EntryDao.Get(ctx, req.ApiCollId, req.ProjectId)
	if err != nil {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_NO_CUSTOM_API,
			ErrMsg: "自定义接口不存在",
		}, nil
	}
	if entryItem.EntryType != uint32(project_entry_api.ENTRY_TYPE_ENTRY_TYPE_API_COLL) {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_NO_CUSTOM_API,
			ErrMsg: "自定义接口不存在",
		}, nil
	}

	hasUpdatePerm := api_common.CheckEntryCanUpdate(sessionItem, projectItem, roleItem, entryItem)

	if !hasUpdatePerm {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := api_coll_dao.ApiGroupDao.Exist(ctx, req.ApiCollId, req.GroupId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_NO_GROUP,
			ErrMsg: "接口集分组不存在",
		}, nil
	}
	count, err := api_coll_dao.ApiItemDao.CountByGroup(ctx, req.ApiCollId, req.GroupId)
	if err != nil {
		return nil, err
	}
	if count > 0 {
		return &http_custom_api.RemoveGroupResponse{
			Code:   http_custom_api.RemoveGroupResponse_CODE_HAS_ITEM,
			ErrMsg: "接口集分组存在接口定义",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = api_coll_dao.ApiGroupDao.Remove(sessCtx, req.ApiCollId, req.GroupId)
		if err != nil {
			return nil, err
		}
		return &http_custom_api.RemoveGroupResponse{
			Code: http_custom_api.RemoveGroupResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*http_custom_api.RemoveGroupResponse), nil
}
